package com.eascs.dubbo.api.internal;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.eascs.admin.api.internal.InternalStartProcessService;
import com.eascs.admin.common.utils.AccountConstants;
import com.eascs.admin.item.service.O2oPubDdItemService;
import com.eascs.admin.o2o.backFees.entity.O2oBackFeesEntity;
import com.eascs.admin.o2o.backFees.service.O2oBackFeesService;
import com.eascs.admin.o2o.enterpriseZX.entity.O2oEnterpriseZxEntity;
import com.eascs.admin.o2o.enterpriseZX.service.O2oEnterpriseZxService;
import com.eascs.admin.o2o.internal.service.PayMentService;
import com.eascs.admin.o2o.internal.service.WfTypeStatusService;
import com.eascs.admin.o2o.internal.util.StatusContexts;
import com.eascs.admin.o2o.loan.entity.O2oLoanapplyEntity;
import com.eascs.admin.o2o.loan.form.PayMentForm;
import com.eascs.admin.o2o.loan.service.O2oChargeSituationService;
import com.eascs.admin.o2o.loan.service.O2oLoanapplyService;
import com.eascs.brand.entity.O2oPartnerEntity;
import com.eascs.brand.service.O2oPartnerService;
import com.eascs.common.util.StringUtil;
import com.eascs.datalist.service.O2oDataListService;
import com.eascs.dubbo.api.util.UserUtils;
import com.eascs.web.sso.User;
import com.eascs.web.sso.UserHolder;
import com.eascs.workflow.WorkFlowConstants;
import com.eascs.workflow.common.entity.sys.HREmployeeAuditor;
import com.eascs.workflow.common.entity.wf.ProcessTemplate;
import com.eascs.workflow.common.service.sys.EmployeeService;
import com.eascs.workflow.common.service.wf.WorkFlowService;
import com.eascs.workflow.common.vo.ModelResult;
import com.eascs.workflow.common.vo.WFRequestParam;
@Service
public class InternalStartProcessServiceImpl implements InternalStartProcessService{
    
	@Reference
	EmployeeService employeeService;
	
	@Reference
	private WorkFlowService workFlowService;
	
	@Autowired
	O2oLoanapplyService o2oLoanapplyService;
	@Autowired
	O2oChargeSituationService o2oChargeSituationService;
	@Autowired
	PayMentService payMentService;
	@Autowired
	O2oPartnerService partnerService;
	@Autowired
	O2oEnterpriseZxService o2oEnterpriseZxService;
	@Autowired
	private O2oDataListService o2oDataListService;
	@Autowired
	O2oPubDdItemService o2oPubDdItemService;
	@Autowired
	O2oBackFeesService o2oBackFeesService;
	@Autowired
	WfTypeStatusService wfTypeStatusService;
	@Value("${o2o.admin.wf.nsUrl}")
	private String nsUrl;
	@Value("${o2o.admin.wf.NewQYZxUrl}")
	private String NewQYZxUrl;
	@Value("${o2o.admin.wf.NewTXUrl}")
	private String NewTXUrl;
	@Override
	public String internalStart(com.eascs.admin.o2o.loan.form.PayMentForm payform) {
		com.eascs.admin.common.vo.ModelResult<Boolean> sumformCheck = payMentService.sumformCheck(payform);
		if(!sumformCheck.isSuccess()){
			return sumformCheck.getErrMsg();
		}
		O2oLoanapplyEntity loan = o2oLoanapplyService.findById(payform.getLoanapplyNo());
		HREmployeeAuditor auditor=employeeService.getAuditorWithNoAndType(loan.getOperatorNo(), "RM");
		WFRequestParam param = new WFRequestParam();
		param.setReferId(loan.getLoanapplyNo());
		param.setReferCode(loan.getBillCode());
		param.setReferUrl(nsUrl);
		param.setSystemModule(ProcessTemplate.SYSTEM_MODULE_O2O);
		if(loan.getLoanType().equals(StatusContexts.LOAN_TYPE_BK)){
			param.setProcessType(ProcessTemplate.PROECESS_TYPE_INAUDIT);
		}else{
			if(loan.getLoanType().equals(StatusContexts.LOAN_TYPE_FQ)||loan.getLoanType().equals(StatusContexts.LOAN_TYPE_EA)){
				param.setProcessType(String.valueOf(ProcessTemplate.PROECESS_TYPE_INAUDIT_FQ));
			}
			if(loan.getLoanType().equals(StatusContexts.LOAN_TYPE_BP) || loan.getLoanType().equals(StatusContexts.LOAN_TYPE_BP_JX) || loan.getLoanType().equals(StatusContexts.LOAN_TYPE_SG) || loan.getLoanType().equals(StatusContexts.LOAN_TYPE_YC) || loan.getLoanType().equals(StatusContexts.LOAN_TYPE_SC)){
				param.setProcessType(String.valueOf(ProcessTemplate.PROECESS_TYPE_INAUDIT_BP));
			}
		}
		param.setProcessVersion("v1");
		User user = UserHolder.getUser();
		param.setAppliedby(user.getNo());
		param.setAppliedbyName(user.getCname());
		param.setOrgNo(loan.getLtd());
		List<String> list=new ArrayList<String>();
		if (StatusContexts.OPERATION_MODEL_ZY.equals(loan.getOperationModel())||StatusContexts.OPERATION_MODEL_YJ.equals(loan.getOperationModel())) { // 佣金跟自营模式不需要过平台总
			if(loan.getLoanType().equals(StatusContexts.LOAN_TYPE_BK)){//终端贷
				list.add(StatusContexts.O2O_WF_CODE_NS_ZJL);
			}
			if(loan.getLoanType().equals(StatusContexts.LOAN_TYPE_FQ)||loan.getLoanType().equals(StatusContexts.LOAN_TYPE_EA)){ //分期贷
				list.add(StatusContexts.O2O_WF_CODE_NS_FQZJL);
			}
			if(loan.getLoanType().equals(StatusContexts.LOAN_TYPE_BP)||loan.getLoanType().equals(StatusContexts.LOAN_TYPE_BP_JX)||loan.getLoanType().equals(StatusContexts.LOAN_TYPE_SG)||loan.getLoanType().equals(StatusContexts.LOAN_TYPE_YC)||loan.getLoanType().equals(StatusContexts.LOAN_TYPE_SC)){ //品牌贷
				list.add(StatusContexts.O2O_WF_CODE_NS_BPZJL);
			}
		}
		Map<String, List<String>> roleUserMap = new HashMap<>();  //指定流程节点由谁经办
		//区域经理
		if (auditor==null) {
			if(loan.getLoanType().equals(StatusContexts.LOAN_TYPE_BK)){//终端贷
				list.add(StatusContexts.O2O_WF_CODE_NS_QYJLSPR);
			}else if (loan.getLoanType().equals(StatusContexts.LOAN_TYPE_BP) || loan.getLoanType().equals(StatusContexts.LOAN_TYPE_BP_JX) || loan.getLoanType().equals(StatusContexts.LOAN_TYPE_SG) || loan.getLoanType().equals(StatusContexts.LOAN_TYPE_YC) || loan.getLoanType().equals(StatusContexts.LOAN_TYPE_SC)) {
				list.add(StatusContexts.O2O_WF_CODE_NS_QYJLSPR_BP);
			}
		}else {
			roleUserMap.put(StatusContexts.ROLE_TYPE_QYJLSPR,Arrays.asList(auditor.getAuditorNo()));
		}
		//信贷经理
		roleUserMap.put(StatusContexts.ROLE_TYPE_NS_XDJL,Arrays.asList(loan.getOperatorNo()));
		param.setRoleUserMap(roleUserMap);
		param.setExcludeNodeCodeList(list);
		param.setLoginUser(UserUtils.getUser(user));
		StringBuffer appliedDes = new StringBuffer("借款人:");
		appliedDes.append(o2oLoanapplyService.findLoanUserEntity(loan.getLoanapplyNo(),loan.getLoanId()).getUserFullName());
		appliedDes.append("，申请金额:");
		java.text.DecimalFormat df=new java.text.DecimalFormat("0.00"); //格式化，保留两位小数 
		appliedDes.append(df.format(loan.getLoanaMount().doubleValue()));
		param.setAppliedDes(appliedDes.toString());
		ModelResult<Boolean> modelResult = workFlowService.instance(param);
		if (modelResult.isSuccess() && modelResult.getModel()) {
			o2oLoanapplyService.updateWorkFlowStatus(StatusContexts.O2O_NS_BEGIN, payform.getLoanapplyNo());
			wfTypeStatusService.updatefindRUN(loan.getLoanapplyNo(), StatusContexts.WFTYPE_NS);
			return null;
		} else {
			return modelResult.getErrMsg();
		}
	}
	@Override
	public String factoryParterStart(String id) {
		ModelResult<Boolean> checkAttachment = partnerService.checkAttachment(id);
		if (!checkAttachment.isSuccess() || !checkAttachment.getModel() ) {
			return checkAttachment.getErrMsg();
		}
		O2oPartnerEntity o2oPartnerEntity = partnerService.getEntityById(id);
		ModelResult<Boolean> checkRole = isCurrentRole(o2oPartnerEntity, "startFlow");
		if (!checkRole.getModel()) {
			return checkRole.getErrMsg();
		}
		ModelResult<Boolean> startUp = partnerService.startUp(id);
		if (startUp.isSuccess() && startUp.getModel()) {
			return null;
		} else {
			return startUp.getErrMsg();
		}
	}
	
	private  ModelResult<Boolean> isCurrentRole(O2oPartnerEntity entity, String operateType) {
		ModelResult<Boolean> modelResult = new ModelResult<>();
		User user = UserHolder.getUser();
		if (!user.getNo().equals(entity.getOperatorId()) && !user.isSuperAdministrator()) {
			if ("edit".equals(operateType)) {
				modelResult.setErrMsg("该信息只能由经办人编辑");
			} else if ("delete".equals(operateType)) {
				modelResult.setErrMsg("该信息只能由经办人删除");
			} else if ("startFlow".equals(operateType)) {
				modelResult.setErrMsg("该流程只能由经办人发起");
			}
			modelResult.setModel(false);
			return modelResult;
		}
		modelResult.setModel(true);
		return modelResult;

	}
	@Override
	public String enterpriseCreditStart(com.eascs.admin.o2o.loan.form.PayMentForm payform) {
		
		O2oEnterpriseZxEntity o2oEnterpriseZxEntity = o2oEnterpriseZxService.getEntityById(payform.getLoanapplyNo());
		if(o2oEnterpriseZxEntity==null){
			return "数据库未查到改企业征信，请联系管理员";
		}
		
		if (!o2oDataListService.checkQYZXApply(o2oEnterpriseZxEntity.getId())){
			return "上传附件未齐全";
		}
		
		if(o2oEnterpriseZxEntity.getZxBank()==null){
			return "请选择征信银行后，再启动流程";
		}

		//一个自然月内在同一家银行仅能查询一次企业征信报告
		if(!StatusContexts.O2O_BANKTYPE_BC.equals(o2oEnterpriseZxEntity.getZxBank())){
			Boolean isMothSelected =o2oEnterpriseZxService.isMothSelectedQYZX(o2oEnterpriseZxEntity.getZxTyshxydm(), o2oEnterpriseZxEntity.getZxBank());
			if(isMothSelected){
				return "一个自然月内在同一家银行仅能查询一次企业征信报告";
			}
		}
		
		WFRequestParam param = new WFRequestParam();
		Map<String, List<String>> roleUserMap = new HashMap<>();  //指定流程节点由谁经办
		//区域经理
		roleUserMap.put(StatusContexts.ROLE_TYPE_QYJLSPR,Arrays.asList(o2oEnterpriseZxEntity.getSubmitId()));
		param.setRoleUserMap(roleUserMap);
		//根据银行去掉节点
		List<String> list=new ArrayList<String>();
		if (!("SPDBGZ".equals(o2oEnterpriseZxEntity.getZxBank()) || "SPDBJN".equals(o2oEnterpriseZxEntity.getZxBank()))) { // 佣金跟自营模式不需要过平台总
			//s
			list.add(WorkFlowConstants.O2O_WF_CODE_QYZX_ZBZXSS1);
			list.add(WorkFlowConstants.O2O_WF_CODE_QYZX_TJR);
			list.add(WorkFlowConstants.O2O_WF_CODE_QYZX_ZBZXSS5);
			//excludeNodeCodeList
		}
		param.setExcludeNodeCodeList(list);
		param.setReferId(o2oEnterpriseZxEntity.getId());
		param.setReferCode(o2oEnterpriseZxEntity.getBillCode());
		param.setReferUrl(NewQYZxUrl); //企业征信详情
		param.setSystemModule(ProcessTemplate.SYSTEM_MODULE_O2O);
		param.setProcessType("E_CREDIT");
		param.setProcessVersion("v1");
		User user = UserHolder.getUser();
		param.setAppliedby(user.getNo());
		param.setAppliedbyName(user.getCname());
		param.setOrgNo(o2oEnterpriseZxEntity.getLtd());
		param.setLoginUser(UserUtils.getUser(user));
		StringBuffer appliedDes = new StringBuffer("姓名:");
		appliedDes.append(o2oEnterpriseZxEntity.getCustomerName());
		appliedDes.append("，征信银行:"+o2oPubDdItemService.findPubdditemNameByCodeisall("BANKTYPEO2O", o2oEnterpriseZxEntity.getZxBank()));
		param.setAppliedDes(appliedDes.toString());
		ModelResult<Boolean> modelResult = workFlowService.instance(param);
		if (modelResult.isSuccess() && modelResult.getModel()) {
			o2oEnterpriseZxEntity.setZxStatus(StatusContexts.WFTYPE_STATUS_RUN);
			o2oEnterpriseZxEntity.setSubmitId(user.getNo());
			o2oEnterpriseZxEntity.setSubmitName(user.getCname());
			o2oEnterpriseZxEntity.setSubmitDate(new Date());
			o2oEnterpriseZxService.update(o2oEnterpriseZxEntity);
			//o2oLoanapplyService.updateWorkFlowStatus(StatusContexts.O2O_ZX_BEGIN, o2oLoanapplyEntity.getLoanapplyNo());
			return null;
		} else {
			return modelResult.getErrMsg();
		}
	}
	@Override
	public String personRefundStart(PayMentForm payform) {
		O2oBackFeesEntity  o2oBackFeesEntity = o2oBackFeesService.queryById(payform.getLoanapplyNo());
		if(o2oBackFeesEntity==null){
			return "数据库未查到个人退款信息，请联系管理员";
		}
		WFRequestParam param = new WFRequestParam();
		param.setReferId(o2oBackFeesEntity.getId());
		param.setReferCode(o2oBackFeesEntity.getBillCode());
		param.setReferUrl(NewTXUrl); //个人退款代办详情
		param.setSystemModule(ProcessTemplate.SYSTEM_MODULE_O2O);
		param.setProcessType("ACCOUNT_REFUND");
		param.setProcessVersion("v1");
		User user = UserHolder.getUser();
		param.setAppliedby(user.getNo());
		param.setAppliedbyName(user.getCname());
		param.setOrgNo(o2oBackFeesEntity.getLtd());
		StringBuffer appliedDes = new StringBuffer("姓名:");
		appliedDes.append(o2oBackFeesEntity.getLoanName());
		appliedDes.append("，金额:"+o2oBackFeesEntity.getBackMoney()+"元");
		param.setAppliedDes(appliedDes.toString());
		param.setLoginUser(UserUtils.getUser(user));
		BigDecimal balance =o2oChargeSituationService.getFreezeBalanceByLoanId(o2oBackFeesEntity.getLoanId());
		if(o2oBackFeesEntity.getBackMoney().compareTo(balance)>0){
			return "退款金额超出可用金额。";
		}
		
		if(o2oBackFeesEntity.getBackMoney().compareTo(BigDecimal.ZERO)==0){
			return "退款金额不能为0";
		}
		//先冻结在调用流程
		String reulst = o2oBackFeesService.ChargingDJ(o2oBackFeesEntity, AccountConstants.ACCOUNT_DJ);
		
		if(StringUtil.isNotBlank(reulst)&&(reulst.equals("SUCCESS")||reulst.equals("ERROR_UNIQUEUD_HAD"))){
			ModelResult<Boolean> modelResult = workFlowService.instance(param);
			if (modelResult.isSuccess() && modelResult.getModel()) {
				o2oBackFeesEntity.setStatus(StatusContexts.WFTYPE_STATUS_RUN);
				o2oBackFeesEntity.setSubmitId(user.getNo());
				o2oBackFeesEntity.setSubmitName(user.getCname());
				o2oBackFeesEntity.setSubmitDate(new Date());
				o2oBackFeesService.update(o2oBackFeesEntity);
				//o2oLoanapplyService.updateWorkFlowStatus(StatusContexts.O2O_ZX_BEGIN, o2oLoanapplyEntity.getLoanapplyNo());
				return null;
			} else {
				return modelResult.getErrMsg();
			}
		}else{
			return reulst;
		}
	}
}
